package top.italks.demo.pay.product.controller;

import top.italks.demo.entity.WXOrderEntity;
import top.italks.demo.pay.common.api.PayService;
import top.italks.demo.pay.common.bean.MethodType;
import top.italks.demo.pay.common.bean.PayOrder;
import top.italks.demo.pay.common.http.HttpConfigStorage;
import top.italks.demo.pay.platform.wx.WXPayConfig;
import top.italks.demo.pay.platform.wx.api.WxPayConfigStorage;
import top.italks.demo.pay.platform.wx.api.WxPayService;
import top.italks.demo.pay.platform.wx.bean.WxTransactionType;
import top.italks.demo.pay.request.QueryOrder;
import top.italks.demo.service.OrderService;
import top.italks.demo.service.WXOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;
import java.util.UUID;

/**
 * 发起支付入口
 *
 * @author: egan
 * @email test@gmail.com
 * @date 2016/11/18 0:25
 */
@RestController
@RequestMapping("/wx")
public class WxPayController {

    private PayService service = null;

    @Resource
    private WXPayConfig wxPayConfig;

    @Autowired
    private OrderService orderService;

    @Autowired
    WXOrderService wxOrderService;

    @PostConstruct
    public void init() {

        service = new WxPayService(new WxPayConfigStorage(wxPayConfig));

        HttpConfigStorage httpConfigStorage = new HttpConfigStorage();

        //最大连接数
        httpConfigStorage.setMaxTotal(20);
        //默认的每个路由的最大连接数
        httpConfigStorage.setDefaultMaxPerRoute(10);
        service.setRequestTemplateConfigStorage(httpConfigStorage);
    }


    /**
     * 获取二维码图像
     * 二维码支付
     *
     * @param price 金额
     * @return 二维码图像
     */
    @RequestMapping(value = "/toQrPay", produces = "image/jpeg;charset=UTF-8")
    public byte[] toWxQrPay(@RequestParam String outTradeNo, @RequestParam String subject,
                            @RequestParam String body, @RequestParam BigDecimal price) throws IOException {
        //获取对应的支付账户操作工具（可根据账户id）
        PayOrder payOrder = new PayOrder();
        payOrder.setOutTradeNo(outTradeNo);
        payOrder.setSubject(subject);
        payOrder.setBody(body);
        payOrder.setPrice(null == price ? new BigDecimal(0.01) : price);
        payOrder.setTransactionType(WxTransactionType.NATIVE);
        BufferedImage bufferedImage = service.genQrPay(payOrder);
        // 支付订单入库
        WXOrderEntity wxOrder = new WXOrderEntity();
        wxOrder.setOut_trade_no(payOrder.getOutTradeNo());
        wxOrder.setBody(payOrder.getSubject());
        wxOrder.setDetail(payOrder.getBody());
        wxOrder.setTotal_fee(payOrder.getPrice().multiply(new BigDecimal(100)).longValue());
        wxOrderService.add(wxOrder);
        // 返回二维码
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "JPEG", baos);
        return baos.toByteArray();
    }

    /**
     * 跳到支付页面
     * 针对实时支付
     * H5支付
     *
     * @param price 金额
     * @return 跳到支付页面
     */
    @RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8")
    public String toPay(HttpServletRequest request, BigDecimal price) {
        top.italks.demo.pay.common.bean.PayOrder order = new top.italks.demo.pay.common.bean.PayOrder
                ("订单title",
                        "摘要",
                        null == price ? new BigDecimal(0.01) : price,
                        UUID.randomUUID().toString().replace("-", ""),
                        WxTransactionType.MWEB);
        order.setSpbillCreateIp(request.getHeader("X-Real-IP"));
        StringBuffer requestURL = request.getRequestURL();
        //设置网页地址
        order.setWapUrl(requestURL.substring(0, requestURL.indexOf("/") > 0 ? requestURL.indexOf("/") : requestURL.length()));
        //设置网页名称
        order.setWapName("在线充值");

        Map orderInfo = service.orderInfo(order);
        return service.buildRequest(orderInfo, MethodType.POST);
    }

    /**
     * 支付回调地址
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "payBack.json")
    public String payBack(HttpServletRequest request) throws IOException {

        //获取支付方返回的对应参数
        Map<String, Object> params = service.getParameter2Map(request.getParameterMap(), request.getInputStream());
        if (null == params) {
            return service.getPayOutMessage("fail", "失败").toMessage();
        }

        //校验
        if (service.verify(params)) {
            // 更新微信支付定单
            String outTradeNo = String.valueOf(params.get("out_trade_no"));
            WXOrderEntity wxOrder = new WXOrderEntity();
            wxOrder.setOut_trade_no(outTradeNo);
            wxOrder.setAppid(String.valueOf(params.get("appid")));
            wxOrder.setBank_type(String.valueOf(params.get("bank_type")));
            wxOrder.setCash_fee(Long.valueOf(String.valueOf(params.get("cash_fee"))));
            wxOrder.setIs_subscribe(String.valueOf(params.get("is_subscribe")));
            wxOrder.setMch_id(String.valueOf(params.get("mch_id")));
            wxOrder.setNotify_url(String.valueOf(params.get("notify_url")));
            wxOrder.setOpenid(String.valueOf(params.get("openid")));
            wxOrder.setResult_code(String.valueOf(params.get("result_code")));
            wxOrder.setReturn_code(String.valueOf(params.get("return_code")));
            wxOrder.setReturn_msg(String.valueOf(params.get("return_msg")));
            wxOrder.setSpbill_create_ip(String.valueOf(params.get("spbill_create_ip")));
            wxOrder.setTime_end(String.valueOf(params.get("time_end")));
            wxOrder.setTrade_type(String.valueOf(params.get("trade_type")));
            wxOrder.setTransaction_id(String.valueOf(params.get("transaction_id")));
            wxOrderService.modifyByOutTradeNo(wxOrder);
            int result = orderService.confirmOrder(outTradeNo);
            if (0 < result) {
                return service.getPayOutMessage("success", "成功").toMessage();
            }
        }

        return service.getPayOutMessage("fail", "失败").toMessage();
    }

    /**
     * 查询
     *
     * @param order 订单的请求体
     * @return 返回查询回来的结果集，支付方原值返回
     */
    @RequestMapping("query")
    public Map<String, Object> query(QueryOrder order) {
        return service.query(order.getTradeNo(), order.getOutTradeNo());
    }

}
